/**
*
*@author Covian,Fernanda V.
*@author Sayes Lucero, Alfredo Andrès Lu:66604
*/
package proycompalex1;
import java.io.*;
/**
 * Clase auxiliar para realizar llamadas al {@link analizadorLex}
 * @author alfredo
 */

public class Main {
    private analizadorLex lexico;
    private FileWriter salida;
    private String args0;
    private String args1;
    private boolean porArchivo=false;
    // archivo de salida, en caso que se haya ingresado uno
    
 /**
 * Método estático que verifica la cantidad argumentos que son pasado y decide
  * donde será mostrado el resultado de analizar lexicalmente el programa fuente. Crea el Objeto Main
  * @param args[0] Nombre del archivo fuente que sera analizado
  * @param args[1] Nombre del archivo opcional que de existir sera el destino de la impresion del resultado
  * de analizar el archivo fuente
  * 
 */
    public static void main(String[] args)
    {
      String arg;
      if ((args.length > 2) || (args.length < 1))
      {
        System.out.println("Cantidad de argumentos invalido");
        System.out.println("<PROGRAM_NAME> <IN_FILE>");
        System.out.println("<PROGRAM_NAME> <IN_FILE> <OUT_FILE>");
        System.exit(0);
      }
      if (args.length == 2)
      {
        Main m = new Main(args[0],args[1]);
      }
      else
      {
        if (args.length == 1)
        {
          Main m = new Main(args[0],"");
        }
      }
    }//main
/**
 * Setea los nombres de archivos pasados por parametros y los almacena en la clase. Es el encargado
 * de comenzar las solicitudes de tokens a travez de la llamada a un metodo privado llamado bigbang.
 * El metodo privado bigbang() itera hasta que el analizador lexico devuelve null, es decir llego al fin de archivo
 * 
 */
    public Main(String args00, String args01)
    {
      this.args0=args00;
      this.args1=args01;
      this.bigbang();
    }//constructor

   /**
    * Solicita Tokens al {@link analizadorLex} mientras no sea fin de archivo.
    * Esta informacion se obtiene cuando el analizador Lexico retorna null.
    */
    private void bigbang()
    {
      token Token;
      String Linea;
      boolean archivoValido=false;
      if (!args1.equals("")){
            porArchivo=true;
            String outfile = args1;
            crearFichero(outfile);
            System.out.println(outfile);
       }//if*/
      else {
        System.out.println("**************************************************");
        System.out.println("*        LISTA DE TOKENS                         *");
        System.out.println("**************************************************");
      }
      if (args0!=null)
      {
        System.out.println(args0);
        archivoValido=verificarArchivoLectura(args0);
        if(archivoValido)
        {
          boolean seguir=true;
          while (seguir)
          {
            Token=null;
            Token=solicitarToken();
            if(Token==null)//llegue a fin de archivo;
            {
              seguir=false;
              imprimir("fin del archivo");
            }
            else
            {
              Linea=armarLinea(Token.getNombre(),Token.getLexema(),Token.getNumLinea());
              imprimir(Linea);
            }
          }
          cerrarArchivo();
        }
        else
        {
            System.out.println("Error el archivo de lectura no es valido");
        }

      }
   }//fin de bigbang
/**
 * Este método crea el archivo de salida
 * @param fichero Nombre del archivo que ingreso el usuario.Debe ser un nombre valido sino genera una excepción
 */
    private void crearFichero(String fichero)
    {
        System.out.println(fichero);
        try
        {
            salida = new FileWriter(fichero,true);
            salida.write("**********************************************************\r\n");
            salida.write("*                LISTA DE TOKENS                         *\r\n");
            salida.write("**********************************************************\r\n");
            System.out.println("El archivo se ha creado correctamente");
        }//try
        catch (IOException ioe) {
            ioe.printStackTrace();
        }//catch
    }//crearFichero

/**
* Este Método, recibe 3 parametros:  el nombre del token, lexema y un entero,
* representando el nùmero de lìnea del archivo. Formate esteticamente una lina para ser impresa
* la que luego serà escrita en el archivo de salida
*@param nombreT Nombre del Token
*@param Lexema Lexema del Token recuperado del archivo fuente
*@param num Número de linea en la que aparece el Token
*/
    private String armarLinea(String nombreT, String Lexema, int num)
    {
        String linea;
        Integer aux = new Integer(num);
        String auxiliar= aux.toString();
        String Arraynum="";
        String ArrayNom="";
        String ArrayLex="";
        int largoNum, largoNom, largoLex;
        largoNum=auxiliar.length();
        if(nombreT==null)
        {
            nombreT="";
            largoNom=0;
        }
        else
        {
           largoNom=nombreT.length();
        }
        largoLex=Lexema.length();
        for (int i=0;i<largoNum;i++)
        {
          Arraynum=Arraynum + auxiliar.charAt(i);
        }
        for (int i=largoNum; i<4;i++)
        {
            Arraynum=Arraynum + " ";
        }
        for (int i=0;i<largoNom;i++)
        {
          ArrayNom=ArrayNom + nombreT.charAt(i);
        }
        for (int i=largoNom; i<13;i++)
        {
            ArrayNom=ArrayNom + " ";
        }
        for (int i=0;i<largoLex;i++)
        {
          ArrayLex=ArrayLex + Lexema.charAt(i);
        }
        for (int i=largoLex; i<13;i++)
        {
            ArrayLex=ArrayLex + " ";
        }
        linea = "Linea:" + Arraynum+"  "+"Token:"+ArrayNom+"  "+"Lexema:"+ArrayLex;
        return linea;
    }
/**
 * Método encargado de cerar el archivo destino en caso de existir
 */
    private void cerrarArchivo()
    {
        try
        {
            if (porArchivo)
            {
                salida.close();
            }
        }
        catch (IOException ioe) {
            ioe.printStackTrace();
        }//catch
    }
/**
 * Metodo
 */
    private void imprimir(String linea)/* imprime la linea en un archivo o pantalla*/
    {
          if (porArchivo && salida !=null)
        {
            try
            {
                if(linea!=null)
                {
                    salida.write("\r\n");
                    salida.write(linea);
                }

            }//try
            catch (IOException ioe)
            {
                ioe.printStackTrace();
            }//catch
        }//if
        else
        {
            if(linea!=null)
            {
                System.out.println(linea);
            }
        }
   }

    private boolean verificarArchivoLectura(String nomArch)
    {
       boolean existioError=false;
       lexico=new analizadorLex(nomArch);
       existioError=lexico.isErrorLectura();
       if(existioError)
       {
         System.out.println("error de lectura en el archivo de lectura");
       }
        return !existioError;
    }


    private token solicitarToken() 
    {
        token t=null;
        try{
            t=lexico.getToken();
        }
        catch(Exception e)
        {
           System.out.println(e.getMessage());
        }
        return t;
    }
}//class
